﻿#include "resource.h"
#include "PluginBrowser.h"
#include "CCefApp.h"
#include "CCefHandler.h"

#include <LuaManager.h>
#include <HLWindows.h>
#include <process.h>

HANDLE handle = nullptr;
CefRefPtr<CCefHandler> g_CefHandler = nullptr;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
unsigned WINAPI ShowDlg(void* param);

PluginBrowser::PluginBrowser()
{
}

PluginBrowser::~PluginBrowser()
{
}

int PluginBrowser::Init()
{
	LuaManager::GetInstance().GetLua().new_usertype<PluginBrowser>("PluginBrowser",
		sol::constructors<PluginBrowser()>(),
		"OpenUrl", &PluginBrowser::OpenUrl
		);
	return 1;
}

int PluginBrowser::Shutdown()
{
	if (handle) CloseHandle(handle);
	return 1;
}

void PluginBrowser::OpenUrl(std::string url)
{
	handle = (HANDLE)_beginthreadex(NULL, NULL, ShowDlg, NULL, NULL, NULL);
}

inline HMODULE ModuleHandleByAddr(const void* ptrAddr)
{
	MEMORY_BASIC_INFORMATION info;
	::VirtualQuery(ptrAddr, &info, sizeof(info));
	return (HMODULE)info.AllocationBase;
}

inline HMODULE ThisModuleHandle()
{
	static HMODULE sInstance = ModuleHandleByAddr((void*)&ThisModuleHandle);
	return sInstance;
}

unsigned WINAPI ShowDlg(void* param)
{
	TCHAR szFilePath[MAX_PATH + 1] = { 0 };
	GetModuleFileName(nullptr, szFilePath, MAX_PATH);
	(wcsrchr(szFilePath, L'\\'))[1] = 0;

	CefEnableHighDPISupport();
	CefMainArgs main_args(ThisModuleHandle());
	int exit_code = CefExecuteProcess(main_args, nullptr, nullptr);
	if (exit_code >= 0)
		// The sub-process has completed so return here.
		return exit_code;

	// Specify CEF global settings here.
	CefSettings settings;
	settings.no_sandbox = true;
	settings.multi_threaded_message_loop = true;

	char szPath[MAX_PATH + 1] = { 0 };
	sprintf_s(szPath, "%ls/cache", szFilePath);
	CefString(&settings.cache_path).FromASCII(szPath);
	sprintf_s(szPath, "%ls/user", szFilePath);
	CefString(&settings.user_data_path).FromASCII(szPath);

	CefString(&settings.locale).FromASCII("zh-CN");
	CefString(&settings.accept_language_list).FromASCII("zh-CN");

	CefRefPtr<CCefApp> app(new CCefApp);
	CefInitialize(main_args, settings, app.get(), nullptr);

	WNDCLASSEXW wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = ThisModuleHandle();
	wcex.hIcon = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ICON1));
	wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"PluginBrowserForm";
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ICON1));
	RegisterClassExW(&wcex);

	HWND hWnd = CreateWindow(L"PluginBrowserForm", L"PluginBrowserForm", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1400, 900, NULL, NULL, ThisModuleHandle(), NULL);
	if (!hWnd) return 0;

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	CefShutdown();
	return (DWORD)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	UINT WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));

	switch (uMsg)
	{
	case WM_CREATE:
		{
			int srcWidth, srcHeight;
			RECT rect;
			//获得屏幕尺寸
			srcWidth = GetSystemMetrics(SM_CXSCREEN);
			srcHeight = GetSystemMetrics(SM_CYSCREEN);
			//取得窗口尺寸
			GetClientRect(hWnd, &rect);
			//重新设置rect里的值
			rect.left = (srcWidth - rect.right) / 2;
			rect.top = (srcHeight - rect.bottom) / 2;
			//移动窗口到指定的位置
			SetWindowPos(hWnd, HWND_TOP, rect.left, rect.top, rect.right, rect.bottom, SWP_HIDEWINDOW);

			g_CefHandler = new CCefHandler(hWnd);
			GetClientRect(hWnd, &rect);
			CefWindowInfo info;
			info.SetAsChild(hWnd, rect);

			CefBrowserSettings settings;
			settings.file_access_from_file_urls = STATE_ENABLED;
			settings.universal_access_from_file_urls = STATE_ENABLED;
			settings.web_security = STATE_ENABLED;

			CefBrowserHost::CreateBrowser(info, g_CefHandler.get(), CefString("http://192.168.200.222/oa"), settings, nullptr);

			ShowWindow(hWnd, SW_SHOWNORMAL);
		}
		break;

	case WM_PAINT:
		HDC hDC;
		PAINTSTRUCT ps;
		hDC = BeginPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
		break;

	case WM_SIZE:
		if (g_CefHandler != nullptr)
		{
			CefRefPtr<CefBrowser> browser = g_CefHandler->GetBrowser();
			if (browser)
			{
				CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
				::MoveWindow(hwnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);  //因为浏览器对于对话框是子窗口，所以浏览器的左上角坐标是相于父窗口的客户区的左上角而言的
			}
		}
		break;

	case WM_CLOSE:
		if (g_CefHandler.get() && !g_CefHandler->IsClosing())
			g_CefHandler->CloseAllBrowsers(false);
		DestroyWindow(hWnd);
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	default:
		if (uMsg == WM_TASKBARCREATED) SendMessage(hWnd, WM_CREATE, wParam, lParam);
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}
